<?php
	/**
	 * html 生成类
	 * detail description
	 * @todo
	 * @author swingcoder <swingcoder@msn.com>
	 * @version 0.1
	 * @copyright Copyright (c) 2009, swingcoder.com
	 */

	class generate
	{
		/**
		 * description
		 * detail description
		 * @param string user
		 * @param integer id
		 * @return int|string|array|object|mixed
		 */
		function generate()
		{
		}

		/**
		 * 执行生成
		 * detail description
		 * @param array ( 'cate_id' => 栏目id, 'rang' => 是否生成已经生成过的 )
		 * @return boolean
		 */
		function gen( $data )
		{
			$result = array( 'success' => false, 'message' => '未知' );

			if ( ! isset( $data['cate_id'] ) )
			{
				$result['message'] = '栏目id为空';
				return $result;
			}

			if ( $data['cate_id'] <= 0 )
			{
				$result['message'] = '栏目id为空';
				return $result;
			}

			$cate_id = $data['cate_id'];
			$rang = isset( $data['rang'] ) ? $data['rang'] : '';
			$html_id = isset( $data['html_id'] ) ? $data['html_id'] : 0;

			$argument = load( 'biz.argument' );

			$cate = load( 'biz.cate' );
			$cate_data = $cate->get( array( 'id' => $cate_id ) );

			$tpl = load( 'biz.tpl' );
			$tpl_data = $tpl->all( array( 'cate_id' => $cate_id ) );

			$tpl_root = config( 'dir.tpl.root' );

			$node_template_file = '';
			$list_template_file = '';
			$content_template_file = '';
			$header_template_file = '';
			$footer_template_file = '';
			$home_template_file = '';
			$other_template_file = '';
			$node_tpl_id = $list_tpl_id = $content_tpl_id = $home_tpl_id = '';
			$header_tpl_id = $footer_tpl_id = $other_tpl_id = '';
			$refer_node_tpl_id = $refer_list_tpl_id = $refer_content_tpl_id = $refer_home_tpl_id = '';
			$refer_header_tpl_id = $refer_footer_tpl_id = $refer_other_tpl_id = '';

			foreach ( $tpl_data['data'] as $index => $value )
			{
				switch ( $value['type'] )	//模板类型
				{
					case $argument->TP_NODE:
						$node_template_file = $tpl_root . $value['path'];
						$node_tpl_id = $value['id'];
						$refer_node_tpl_id = empty( $value['refer_tpl_id'] ) ? 0 : $value['refer_tpl_id'];
						break;

					case $argument->TP_LIST:
						$list_template_file =  $tpl_root . $value['path'];
						$list_tpl_id = $value['id'];
						$refer_list_tpl_id = empty( $value['refer_tpl_id'] ) ? 0 : $value['refer_tpl_id'];
						break;

					case $argument->TP_CONTENT:
						$content_template_file =  $tpl_root . $value['path'];
						$content_tpl_id = $value['id'];
						$refer_content_tpl_id = empty( $value['refer_tpl_id'] ) ? 0 : $value['refer_tpl_id'];
						break;

					case $argument->TP_HOME:
						$home_template_file =  $tpl_root . $value['path'];
						$home_tpl_id = $value['id'];
						$refer_home_tpl_id = empty( $value['refer_tpl_id'] ) ? 0 : $value['refer_tpl_id'];
						break;

					case $argument->TP_HEADER:
						$header_template_file =  $tpl_root . $value['path'];
						$header_tpl_id = $value['id'];
						$refer_header_tpl_id = empty( $value['refer_tpl_id'] ) ? 0 : $value['refer_tpl_id'];
						break;

					case $argument->TP_FOOTER:
						$footer_template_file =  $tpl_root . $value['path'];
						$footer_tpl_id = $value['id'];
						$refer_footer_tpl_id = empty( $value['refer_tpl_id'] ) ? 0 : $value['refer_tpl_id'];
						break;

					case $argument->TP_OTHER:
						$other_template_file =  $tpl_root . $value['path'];
						$other_tpl_id = $value['id'];
						$refer_other_tpl_id = empty( $value['refer_tpl_id'] ) ? 0 : $value['refer_tpl_id'];
						break;

					default:
				}
			}

			//生成内容页
			$ok = $this->gen_content( array( 'module_type_id' => $cate_data['module_type_id'], 'cate_id' => $cate_id, 'tpl' => $content_template_file, 'html_id' => $html_id, 'rang' => $rang, 'tpl_id' => $content_tpl_id, 'refer_tpl_id' => $refer_content_tpl_id  ) );
			if ( ! $ok['success'] )
			{
				return $ok;
			}

			//生成列表页
			$ok = $this->gen_list( array(  'module_type_id' => $cate_data['module_type_id'], 'cate_id' => $cate_id, 'tpl' => $list_template_file, 'html_id' => $html_id, 'rang' => $rang, 'pagesize' => $cate_data['pagesize'], 'tpl_id' => $list_tpl_id, 'refer_tpl_id' => $refer_list_tpl_id  ) );
			if ( ! $ok['success'] )
			{
				return $ok;
			}

			//生成节页
			$ok = $this->gen_node( array(  'module_type_id' => $cate_data['module_type_id'], 'cate_id' => $cate_id, 'tpl' => $node_template_file, 'html_id' => $html_id, 'rang' => $rang, 'tpl_id' => $node_tpl_id, 'refer_tpl_id' => $refer_node_tpl_id ) );

			$result = $ok;

			return $result;
		}

		/**
		 * 生成内容页html
		 * @param array
		 * @module_type_id 内容模型id
		 * @cate_id 当有值时生成栏目下所有未生成的页面
		 * @tpl 模板文件路径
		 * @rang 是否生成已经发布的 all全部
		 * @return boolean
		 */
		function gen_content( $data )
		{
			extract( $data, EXTR_OVERWRITE );

			$result = array( 'success' => false, 'message' => '[func:gen_content]未知' );
			$tpl = str_replace( '//', '/', $tpl );

			$template = load( 'template', array( 'domain' => 'tpl' ) );

			if ( is_file( $tpl ) && is_readable( $tpl ) )
			{
				//获取标签定义
				$tag = load( 'biz.tpl_tag_define' );
				$tag_value = $tag->all( array( 'tpl_id' => ( $data['refer_tpl_id'] == 0 ? $data['tpl_id'] : $data['refer_tpl_id'] ) ) );

				//获取未发布的记录
				if ( $cate_id != 0 )
				{
					$argument = load( 'biz.argument' );
					$cate = load( 'biz.cate' );
					$cate_dir = $cate->getdir( $cate_id );
					$html = load( 'biz.html' );
					$tmp = $html->all( array( 'cate_id' => $cate_id, 'saved' => ( $rang == 'all' ? '' : 0 ), 'ext_table' => $argument->content_module[$module_type_id], 'audit_flag' => 1, 'size' => 999999 ) );
					foreach ( $tmp['data'] as $index => $value )	//生成多个content页，每条记录生成一页
					{
						//具体数据的提供应该移到标签库去实现.
						if ( $module_type_id == $argument->CM_NEWS )
						{
							$value['preview_page_url'] = $value['next_page_url'] = '#';
							if ( isset( $tmp['data'][$index-1] ) )
							{
								$value['preview_page_url'] = '/' . $cate_dir['dir'] . 'content_' . ( $tmp['data'][$index-1]['id'] ) . '.htm';
							}
							if ( isset( $tmp['data'][$index+1] ) )
							{
								$value['next_page_url'] =  '/' . $cate_dir['dir'] . 'content_' . ( $tmp['data'][$index+1]['id'] ) . '.htm';
							}
							$value['content'] = $value['content'];
						}
						if ( $module_type_id == $argument->CM_PHOTO )
						{

						}
						if ( $module_type_id == $argument->CM_VIDEO )
						{

						}
						$path = config( 'dir.www' ) . $cate_dir['dir'] . 'content_' . $value['id'] . '.htm';
						$path = str_replace( '//', '/', $path );

						$value['tag_value'] = $tag_value;
						$result = $this->gen_one_html( $value, $tpl, $path );
						if ( $result['success'] == false )
						{
							return $result;
						}
					}
					$result['success'] = true;
				}
				else
				{
					$result['message'] = '栏目不存在';
					return $result;
				}
			}
			else
			{
				$result['message'] = '模板文件不存在' . $tpl;
				return $result;
			}

			return $result;
		}


		/**
		 * 生成列表html
		 * @param array
		 * @module_type_id 内容模型id
		 * @cate_id 当有值时生成栏目下所有未生成的页面，与html_id互斥
		 * @html_id 当有值时仅生成一个页面
		 * @tpl 模板文件路径
		 * @rang 是否生成已经发布的 all全部
		 * @pagesize 页大小
		 * @return boolean
		 */
		function gen_list( $data )
		{
			extract( $data, EXTR_OVERWRITE );

			$result = array( 'success' => false, 'message' => '[func:gen_list]未知' );

			if ( $cate_id == 0 || empty( $tpl ) || empty( $tpl_id ) )
			{
				$result['message'] = '参数错误';
				return $result;
			}

			if ( ! is_file( $tpl ) || ! is_readable( $tpl ) )
			{
				$result['message'] = '模板文件不存在' . $tpl;
				return $result;
			}

			$template = load( 'template' );

			$cate = load( 'biz.cate' );
			$cate_dir = $cate->getdir( $cate_id );
			$html = load( 'biz.html' );
			$page = 1;

			//取回该栏目所有记录
			$argument = load( 'biz.argument' );
			$tmp = $html->all( array( 'cate_id' => $cate_id, 'saved' => '', 'ext_table' => $argument->content_module[$module_type_id], 'size' => 999999, 'page' => $page, 'audit_flag' => 1 ) );

			//分页处理
			$tmp['size'] = $pagesize;	//通过栏目属性传递进来
			$tmp['page'] = ceil( $tmp['total'] / $tmp['size'] );
			$navigation = load( 'navigation' );
			$totalpage = $tmp['page'];

			//获取标签定义
			$tag = load( 'biz.tpl_tag_define' );
			$tag_value = $tag->all( array( 'tpl_id' => ( $data['refer_tpl_id'] == 0 ? $data['tpl_id'] : $data['refer_tpl_id'] ) ) );

			$value = array();
			$value['tag_value'] = $tag_value;

			//即使没有记录，也要生成一个空白文件
			if ( $totalpage > 0 )
			{
				for ( $i = 0; $i < $totalpage; $i++ )
				{
					$tmp['current'] = $i + 1;
					$list_item = array_slice( $tmp['data'], $i * $tmp['size'], $tmp['size'] );
					$value['list_item'] = $list_item;

					$bar = $navigation->compute( $tmp['total'], $tmp['size'], $tmp['page'], array( 'page' => $tmp['current'] ) );
					$value['bar'] = $this->parse_page_bar( $bar, $cate_dir['dir'] );
					$navigation->link_argument = '?';	//important !!

					$path = config( 'dir.www' ) . $cate_dir['dir'] . 'list_' . $tmp['current'] . '.htm';
					$path = str_replace( '//', '/', $path );

					$result = $this->gen_one_html( $value, $tpl, $path );
					if ( $result['success'] == false )
					{
						return $result;
					}
				}
			}
			else
			{
				$path = config( 'dir.www' ) . $cate_dir['dir'] . 'list_1.htm';
				$path = str_replace( '//', '/', $path );
				$value['list_item'] = array();
				$result = $this->gen_one_html( $value, $tpl, $path );
				if ( $result['success'] == false )
				{
					return $result;
				}
			}

			return $result;
		}


		/**
		 * 生成栏目节点html
		 * @param array
		 * @module_type_id 内容模型id
		 * @cate_id 当有值时生成栏目下所有未生成的页面，与html_id互斥
		 * @html_id 当有值时仅生成一个页面
		 * @tpl 模板文件路径
		 * @rang 是否生成已经发布的 all全部
		 * @return boolean
		 */
		function gen_node( $data )
		{
			extract( $data, EXTR_OVERWRITE );

			$result = array( 'success' => false, 'message' => '[func:gen_node]未知' );

			$template = load( 'template' );

			$argument = load( 'biz.argument' );
			$cate = load( 'biz.cate' );
			$cate_dir = $cate->getdir( $cate_id );
			$path = config( 'dir.www' ) . $cate_dir['dir'] . 'index.htm';
			$path = str_replace( '//', '/', $path );
			$list_first_file = config( 'dir.www' ) . $cate_dir['dir'] . 'list_1.htm';
			$list_first_file = str_replace( '//', '/', $list_first_file );

			if ( is_file( $tpl ) && is_readable( $tpl ) )
			{
				//获取标签定义
				$tag = load( 'biz.tpl_tag_define' );
				$tag_value = $tag->all( array( 'tpl_id' => ( $data['refer_tpl_id'] == 0 ? $data['tpl_id'] : $data['refer_tpl_id'] ) ) );

				$result = $this->gen_one_html( array( 'tag_value' => $tag_value ), $tpl, $path );
				if ( $result['success'] == false )
				{
					return $result;
				}
			}
			else
			{
				//模板不存在，取列表第一页为节点页
				if ( is_file( $list_first_file ) )
				{
					if ( copy( $list_first_file, $path ) )
					{
						$result['success'] = true;
					}
					else
					{
						$result['message'] = '复制文件失败' . $list_first_file . '->' . $path;
						return $result;
					}
				}
			}

			return $result;
		}


		/**
		 * 生成首页html
		 *
		 * @param integer cate_id 当有值时生成栏目下所有未生成的页面，与html_id互斥
		 * @param integer html_id 当有值时仅生成一个页面
		 * @param string template 模板文件路径
		 * @return boolean
		 */
		function gen_home()
		{
			$result = array( 'success' => false, 'message' => '未知' );
			$argument = load( 'biz.argument' );
			$tpl = load( 'biz.tpl' );
			$tmp = $tpl->all( array( 'type' => $argument->TP_HOME ) );
			$data = $tmp['data'][0];

			if ( ! empty( $data ) )
			{
				$path = config( 'dir.www' ) . 'index.htm';
				$path = str_replace( '//', '/', $path );
				$tpl_file = config( 'dir.tpl.root' ) . $data['path'];
				$tpl_file = str_replace( '//', '/', $tpl_file );

				if ( is_file( $tpl_file ) && is_readable( $tpl_file ) )
				{
					//获取标签定义
					$tag = load( 'biz.tpl_tag_define' );
					$tag_value = $tag->all( array( 'tpl_id' => ( empty( $data['refer_tpl_id'] ) ? $data['id'] : $data['refer_tpl_id'] ) ) );

					$result = $this->gen_one_html( array( 'tag_value' => $tag_value ), $tpl_file, $path );
					if ( $result['success'] == false )
					{
						return $result;
					}
					else
					{
						@copy( $path, config( 'dir.root' ) . 'index.htm' );
					}
				}
				else
				{
					$result['message'] = '模板文件不存在' . $tpl_file;
					return $result;
				}
			}
			else
			{
				$result['message'] = '请先添加首页模板文件';
				return $result;
			}

			return $result;
		}

		/**
		 * 生成模板属性为其它的页面
		 * detail description
		 * @param string user
		 * @param integer id
		 * @return int|string|array|object|mixed
		 */
		function gen_other()
		{
			$result = array( 'success' => false, 'message' => '未知' );

			$argument = load( 'biz.argument' );
			$tpl = load( 'biz.tpl' );
			$tmp = $tpl->all( array( 'type' => $argument->TP_OTHER ) );
			$data = $tmp['data'];

			if ( ! empty( $data ) && count( $data ) > 0 )
			{
				foreach ( $data as $index => $value )
				{
					$basename = basename( $value['path'] );
					$html_path = config( 'dir.www' ) . $basename;
					$html_path = str_replace( '//', '/', $html_path );
					$tpl_file = config( 'dir.tpl.root' ) . $value['path'];
					$tpl_file = str_replace( '//', '/', $tpl_file );

					//获取标签定义
					$tag = load( 'biz.tpl_tag_define' );
					$tag_value = $tag->all( array( 'tpl_id' => ( empty( $value['refer_tpl_id'] ) ? $value['id'] : $value['refer_tpl_id'] ) ) );

					$result = $this->gen_one_html( array( 'tag_value' => $tag_value ), $tpl_file, $html_path );
				}
			}

			return $result;
		}


		/**
		 * 分析模板页面，替换模板内容
		 *
		 * @param string pass_vars
		 * @param string tpl_path
		 * @param string html_path
		 * @return array
		 */
		function gen_one_html( $pass_vars, $tpl_path, $html_path )
		{
			$result = array( 'success' => false, 'message' => '未知' );
			$template = load( 'template' , array( 'domain' => 'tpl.www' ) );

			//分析标签定义
			if ( isset( $pass_vars['tag_value'] ) && count( $pass_vars['tag_value'] ) > 0 )
			{
				$tags = $pass_vars['tag_value']['data'];
				foreach ( $tags as $index => $tag )
				{
					$datawarehouse = $this->parse_datawarehouse( $tag );
					if ( $datawarehouse['success'] === false )
					{
						$result['message'] = '标签语法分析失败.' ;
						return $result;
					}
					else
					{
						if ( ! isset( $datawarehouse['data'] ) )
						{
							$datawarehouse['data'] = array();
						}
						$pass_vars = array_merge( $pass_vars, $datawarehouse['data'] );
					}
				}
			}

			//获取配置参数
			$argument = load( 'biz.argument' );
			$argument_data = $argument->all( array( 'size' => 9999 ) );
			//数据扁平化
			$_argument = array();
			foreach ( $argument_data['data'] as $aindex => $avalue )
			{
				$_argument[$avalue['ename']] = $avalue['value'];
			}
			$pass_vars['_argument'] = $_argument;

			//查找栏目定义的seo参数,如果有定义,需要覆盖基本参数的定义
			if ( isset( $pass_vars['cate_id'] ) )
			{
				$cate = load( 'biz.cate' );
				$tmp = $cate->get( array( 'id' => $pass_vars['cate_id'] ) );
				foreach ( $pass_vars['_argument'] as $index => $value )
				{
					if ( isset( $tmp[$index] ) && ! empty( $tmp[$index] ) )
					{
						$pass_vars['_argument'][$index] = $tmp[$index];
					}
				}
			}

			$cate_relative_path = substr( $html_path, strlen( config( 'dir.www' ) ), ( strrpos( $html_path, "/" ) - strlen( config( 'dir.www' ) ) + 1 ) );	//没有 / 前缀
			$url_relative_path = substr( config( 'domain.www' ), 0, strlen( config( 'domain.www' ) ) -1 );
			//$url_relative_path = config( 'domain.www' );

			$pass_vars['cate_path'] = $cate_relative_path;


			$template->appoint( $pass_vars );
			$data =	$template->parse( substr( $tpl_path, strlen( $template->path ) ) );



			//修正素材引用的路径
			//用..引用上一级的路径方式没有替换
			//upload路径与其它资源不平级,要作特殊替换
			$pattern = array( '/ href=["\']{1}([^h\/\.\.][^"\']+\.css)["\']{1} /i', '/ src=["\']{1}([^h\/\.\.].*\.js)["\']{1} [^"\']/i', '/ href=["\']{1}([^h\.\.][^"\'>]+)["\']{1}/i', '/ src=["\']{1}(\/upload\/.*\..*)["\']{1}/i', '/ src=["\']{1}([^h\.\.\/].*\..*)["\']{1}/i' );

			$replace = array( ' href="' . $template->auto['_tpl']['url.root'] . '\\1" ', ' src="' . $template->auto['_tpl']['url.root'] . '\\1" ', ' href="' . $url_relative_path . '\\1"', ' src="' . preg_replace( '/\/$/', '', config( 'domain.tpl.root' ) ) . '\\1"', ' src="' . $template->auto['_tpl']['url.root'] . '\\1"' );
			$data  = preg_replace( $pattern, $replace, $data );

			if ( ! $this->write_html( $data, $html_path ) )
			{
				$result['message'] = '写入文件失败。' . $html_path;

				return $result;
			}
			else
			{
				//更新数据库文件路径记录
				if ( isset( $pass_vars['id'] ) && preg_match( '/^\d+/', $pass_vars['id'] ) )	 //是否有传递html_id
				{
					$html = load( 'biz.html' );
					$html->update_save_path( $pass_vars['id'], substr( $html_path, strlen( config( 'dir.www' ) ) - 1 ) );
				}
			}

			$result['success'] = true;

			return $result;
		}


		/**
		 * 写文件
		 * detail description
		 * @param string data
		 * @param string path 绝对物理路径
		 * @return boolean
		 */
		function write_html( $data, $path )
		{
			if ( empty( $path ) || empty( $data ) )
			{
				return false;
			}

			$info = pathinfo( $path );

			if ( ! is_dir( $info['dirname'] ) )
			{
				if ( ! mkdir( $info['dirname'], 0755, true ) )
				{
					return false;
				}
			}
			if ( ! is_writable( $info['dirname'] ) )
			{
				return false;
			}

			if ( ! file_put_contents( $path, $data, LOCK_EX ) )
			{
				return false;
			}

			return true;
		}

		/**
		 * 处理分页链接
		 * detail description
		 * @param array bar 分页参数
		 * @return arrray
		 */
		function parse_page_bar( $bar, $cate_dir = '' )
		{
			if ( is_array( $bar ) )
			{
				$bar['first_link'] = preg_replace( '/\?page=(\d+)/i', '/' . $cate_dir . 'list_\\1.htm', $bar['first_link'] );
				$bar['last_link'] = preg_replace( '/\?page=(\d+)/i', '/' . $cate_dir . 'list_\\1.htm', $bar['last_link'] );
				$bar['prev_link'] = preg_replace( '/\?page=(\d+)/i', '/' . $cate_dir . 'list_\\1.htm', $bar['prev_link'] );
				$bar['next_link'] = preg_replace( '/\?page=(\d+)/i', '/' . $cate_dir . 'list_\\1.htm', $bar['next_link'] );
				foreach ( $bar['number'] as $index => $value )
				{
					$bar['number'][$index]['link'] = preg_replace( '/\?page=(\d+)/i', '/' . $cate_dir . 'list_\\1.htm', $bar['number'][$index]['link'] );
				}
			}

			return $bar;
		}


		/**
		 * 分析模板文中定义的数据结构
		 * 模板文件中定义的变量需要支持多次include
		 * @param array $datawarehouse( table tag and table tpl_tag_define union)
		 * @return array( 'success'=>true, 'data' => mixed , 'message'=>'' )
		 */
		function parse_datawarehouse( $datawarehouse )
		{
			$result = array( 'success' => false, 'data' => array(), 'message' => '' );

			$taglib = load( 'biz.taglib' );

			$tmp1 = array();
			$tmp1['var_name'] = $datawarehouse['var_name'];
			$tmp1['tpl_id'] = $datawarehouse['tpl_id'];
			$tmp1['tagtype'] = $datawarehouse['class_name'];
			$tmp1['argument'] = $datawarehouse['argument'];

			//$str = json_encode( $tmp1 );
			$str = '{"var_name":"'.$tmp1['var_name'].'", "tpl_id":'.$tmp1['tpl_id'].', "tagtype":"'.$tmp1['tagtype'].'", "argument":'.$tmp1['argument'].' }';

			$tmp = $taglib->result( $str );
			if ( $tmp['success'] === false )
			{
				return $tmp;
			}

			$result['data'][$datawarehouse['var_name']] = $tmp['data'];
			$result['success'] = true;
			return $result;
		}

	}
?>